#include "form_light_lamp.h"
#include "ui_form_light_lamp.h"

// add necessary includes here
#include "utils/can/can_bll_t1c.h"
#include "ui/share/qlineloading.h"


/*
 * Function:    FormLightLamp
 * Description: The default constructor
 * Paramer:     void
 * Return:
 */
FormLightLamp::FormLightLamp(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::FormLightLamp)
{
    qDebug() << Q_FUNC_INFO;

    ui->setupUi(this);
}

/*
 * FormLightLamp:    ~FormLightLamp
 * Description: The default destructor
 * Paramer:     void
 * Return:
 */
FormLightLamp::~FormLightLamp()
{
    qDebug() << Q_FUNC_INFO;

    delete ui;
}

/*
 * Function:    getInstance
 * Description: Get an instance of "FormLightLamp" class, if exist, return it
 * Paramer:     QWidget *pParent - the pointer of QWidget class
 * Return:      the pointer of "FormStartupTest" class
 */
FormLightLamp* FormLightLamp::getInstance(QWidget *pParent)
{
    // Set to a null pointer to make the window occupy full screen
//    pParent = nullptr;

    static FormLightLamp *pNew = NULL;
    if(!pNew) {
        qDebug() << Q_FUNC_INFO;

        // Create a new object if it doesn't exist
        pNew = new FormLightLamp(pParent);
        if(NULL == pNew) return NULL;

        // After constructing object, initialize the object
        pNew->_Initialze();

        // Initialize control's UI
        pNew->_InitUi();

        // Hide widget firstly
        pNew->hide();
    }
    else {
        // Set the parent object
        pNew->setParent(pParent);
    }

    return pNew;
}

/*
 * Function:    _Initialze
 * Description: After constructing object, initialize the object
 * Paramer:     void
 * Return:      void
 */
void FormLightLamp::_Initialze()
{
    qDebug() << Q_FUNC_INFO;

    if(!m_pTimer) m_pTimer = new QTimer(this);
    Q_ASSERT(m_pTimer);
    m_pTimer->setInterval(DEF_SEC_INTERVAL);

    // Signal-slot initialization
    std::vector<bool> vecConnect;
    vecConnect.push_back(QObject::connect(m_pTimer, SIGNAL(timeout()), this, SLOT(slotLightTimeout()), static_cast<Qt::ConnectionType>(Qt::AutoConnection | Qt::UniqueConnection)));
    vecConnect.push_back(QObject::connect(CanBLL_T1C::getInstance(this), SIGNAL(signalDoorStatusDetected(unsigned int, QStringList, int)), this, SLOT(slotDoorStatusDetected(unsigned int, QStringList, int)), static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::UniqueConnection)));
    for(int i=0; i<(int)vecConnect.size(); i++) {
        Q_ASSERT(vecConnect.at(i));
    }
}

/*
* Function:		_InitUi
* Description:	Init the window style
* Paramer:		void
* Return:		void
*/
void FormLightLamp::_InitUi()
{
    qDebug() << Q_FUNC_INFO;

    // Displays the background image of the window
    QWidget::setAttribute(Qt::WA_StyledBackground);

    SET_STYLE_SHEET(QString(":/%1/factory/uvc/%2.qss").arg("skin_1").arg(this->objectName()));

    // Hide the title bar
    this->setWindowFlags(Qt::FramelessWindowHint);

    ui->label_Prompt_Info->setWordWrap(true);
    ui->pushButton_Confirm->setFocusPolicy(Qt::NoFocus);

    // Adjust the position
    this->move(0, 0);
    this->hide();
}

/*
* Function:		changeEvent
* Description:	Triggers an event before it is switch language
* Paramer:		QShowEvent *event - the pointer of "QEvent"
* Return:		void
*/
void FormLightLamp::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);

    switch (e->type())
    {
    case QEvent::LanguageChange:
        qDebug() << Q_FUNC_INFO;

        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void FormLightLamp::on_pushButton_Confirm_clicked()
{
    if(m_pTimer->isActive()) {
        m_pTimer->stop();

        QTimer::singleShot(100, this, [=]{
            // Turn on the UV lamp
            CanBLL_T1C::getInstance(this)->controlLamp(CanVars::gs_nIapCanID_CH1, false);
        });
    }

    this->hide();
}

/*
* Function:		setPromptInfo
* Description:	Close the window after click the button
* Paramer:		QString sTitle - title name
*               QString sPromptInfo - prompt info
*               bool bShowConform - is show conform button
*               int nTimeout - timeout
* Return:		void
*/
void FormLightLamp::setPromptInfo(QString sTitle, QString sPromptInfo, int nTimeout)
{
    qDebug() << Q_FUNC_INFO << sTitle << sPromptInfo << nTimeout;
    m_nTimeRemain = nTimeout;

    // Update the prompt info
    ui->label_PageTitle->setText(sTitle);
    ui->label_Prompt_Info->setText(sPromptInfo);
    ui->label_Shutdown->setText(QString("%1").arg(_seconds2Time(m_nTimeRemain / DEF_SEC_INTERVAL)));

    if(m_pTimer) {
        m_pTimer->start();
    }

    this->setGeometry(0, 0, DEF_MAINFRAME_WIDTH, DEF_MAINFRAME_HEIGHT);
    this->show();

    QTimer::singleShot(100, this, [=]{
        // Turn on the UV lamp
        CanBLL_T1C::getInstance(this)->controlLamp(CanVars::gs_nIapCanID_CH1, true);
    });
}

/*
* Function:		slotLightTimeout
* Description:	Timeout for disinfect
* Paramer:		void
* Return:		void
*/
void FormLightLamp::slotLightTimeout()
{
    m_nTimeRemain -= DEF_SEC_INTERVAL;

    if(0 > m_nTimeRemain) {
        m_pTimer->stop();
        this->hide();

        QTimer::singleShot(100, this, [=]{
            // Turn on the UV lamp
            CanBLL_T1C::getInstance(this)->controlLamp(CanVars::gs_nIapCanID_CH1, false);
        });
    }
    else {
        ui->label_Shutdown->setText(QString("%1").arg(_seconds2Time(m_nTimeRemain / DEF_SEC_INTERVAL)));
    }
}

/*
 * Function:    slotDoorStatusDetected
 * Description: Notify the door status
 * Paramer:     unsigned int unCanId - CAN ID
 *              QStringList lstJsonParams - door status code
 *              int nResult - error coding
 * Return:      int - the error code, 0:success; otherwise: failure
 */
void FormLightLamp::slotDoorStatusDetected(unsigned int unCanId, QStringList lstJsonParams, int nResult)
{
    qDebug() << Q_FUNC_INFO << unCanId << lstJsonParams << nResult;

    if(0 < lstJsonParams.size()) {
        if(0 < lstJsonParams.at(0).toInt()) {
            if(m_pTimer->isActive()) {
                m_pTimer->stop();

                ui->label_PageTitle->setText(tr("Prompt"));
                ui->label_Prompt_Info->setText(tr("The warehouse door is open, and UV disinfection has stopped"));
                ui->label_Shutdown->setText("");
                ui->pushButton_Confirm->setText(tr("Confirm"));

                QTimer::singleShot(100, this, [=]{
                    // Turn on the UV lamp
                    CanBLL_T1C::getInstance(this)->controlLamp(CanVars::gs_nIapCanID_CH1, false);
                });
            }
        }
    }
}

/*
 * Function:    _seconds2Time
 * Description: Convert seconds to time
 * Paramer:     int nSeconds - countdown by second
 * Return:      QString - time
 */
QString FormLightLamp::_seconds2Time(int nSeconds)
{
    QString sTime = "";
    int nHours = 0;
    int nMinutes = 0;

    nHours= nSeconds / 3600;
    nSeconds %= 3600;
    nMinutes = nSeconds / 60;
    nSeconds %= 60;

    sTime = QString("%1").arg(nHours, 2, 10, QLatin1Char('0'))
            + ":"
            + QString("%1").arg(nMinutes, 2, 10, QLatin1Char('0'))
            + ":"
            + QString("%1").arg(nSeconds, 2, 10, QLatin1Char('0'));

//    qDebug() << Q_FUNC_INFO << nSeconds << sTime;
    return sTime;
}
